//
//  MyApiManager.swift
//  YiZhangGui
//
//  Created by Mac on 2018/1/23.
//  Copyright © 2018年 Mac. All rights reserved.
//

import Foundation
import UIKit
import AdSupport
import RxSwift
import Moya
import Moya_ObjectMapper

private func JSONResponseDataFormatter(_ data: Data) -> Data {
    do {
        let dataAsJSON = try JSONSerialization.jsonObject(with: data)
        let prettyData =  try JSONSerialization.data(withJSONObject: dataAsJSON, options: .prettyPrinted)
        return prettyData
    } catch {
        return data //fallback to original data if it cant be serialized
    }
}
/// MARK: - Provider setup
let spinerPlugin = NetworkActivityPlugin { (state, type)  in
    if state == .began {  // 有网络活动时
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
    } else {              // 网络活动停止时或者没有网络活动时都会执行
        UIApplication.shared.isNetworkActivityIndicatorVisible = false
    }
    
}
let provider = MoyaProvider<MyApiManager>(plugins: [AccessTokenPlugin(verbose: true, responseDataFormatter: JSONResponseDataFormatter)])

let disposeBag = DisposeBag()

func cancelAllRequest() { provider.session.cancelAllRequests() }

//定义下载的DownloadDestination（不改变文件名，遇到同名文件会覆盖）
private let defaultDownloadDestination: DownloadDestination = { temporaryURL, response in
    return (defaultDownloadDir.appendingPathComponent(response.suggestedFilename!),
            [.removePreviousFile])
}
//默认下载保存地址（用户文档目录） NSTemporaryDirectory
let defaultDownloadDir: URL = {
    let directoryURLs = FileManager.default.urls(for: .documentDirectory,
                                                 in: .userDomainMask)
    return directoryURLs.first ?? URL(fileURLWithPath: NSTemporaryDirectory())
}()
///
public enum MyApiManager {
    // 检测更新
    case checkUpdate
    
    /// 注销账号
    case deleteAccount
    
    /// 多文件上传 上传照片
    case uploadSiteFiles(images: [UIImage])

    // MARK: 系统操作
    /// 登录
    case login(userName: String, code: String)
    case SmsCode(phone: String)
    /// 易掌柜角色登录
    case loginpwd(userName: String, passWord: String)
    case pwdReset(phone: String, code: String, password: String, re_password: String)
    
    case upDeviceToken(token: String, come_from: String, device: String, login_account: String)

    // 上传照片
    case uploadImg(img: UIImage)
    //上传文件
    case uploadFile(filePath : NSString)
    
    case getDataUploadWorkbench
    
    
}

extension MyApiManager: TargetType {
    /// BaseURL
    public var baseURL: URL {
        
     
//    switch self {
//
//        case .downLoadJson:
//
//            return URL(string: Macro_URLs.downLoadUrl)!
//        default:
//            return URL(string: Macro_URLs.baseURL)!
//
//    }
        
//        switch self {
//           case .downLoadJson:
//               guard let downloadURL = URL(string: Macro_URLs.downLoadUrl) else {
//                   fatalError("Invalid download URL")
//               }
//               return downloadURL
//        case .loadWeb:
//                guard let downloadURL = URL(string: Macro_URLs.webUrl) else {
//                    fatalError("Invalid download URL")
//                }
//                return downloadURL
//           default:
//               guard let baseURL = URL(string: Macro_URLs.baseURL) else {
//                   fatalError("Invalid base URL")
//               }
//               return baseURL
//           }
        return URL(string: Macro_URLs.baseURL)!

                
    }
    
    /// 将被追加到“baseURL”的路径，形成完整的“URL”。
    public var path: String {
        switch self {
            /// 检测更新
            
        case .checkUpdate:
            return "/site/update"
            
            /// 注销账号
        case .deleteAccount:
            return "/sr-user/delete-mpc-or-sr"
            
        case .uploadSiteFiles:
            return "/site/multiple-upload"
            
            
        case .login(userName: let userName, code: let code):
           return ""
        case .SmsCode(phone: let phone):
            return ""
        case .loginpwd(userName: let userName, passWord: let passWord):
            return ""
        case .pwdReset(phone: let phone, code: let code, password: let password, re_password: let re_password):
            return ""
        case .upDeviceToken(token: let token, come_from: let come_from, device: let device, login_account: let login_account):
            return ""
        case .uploadImg(img: let img):
            return ""
        case .uploadFile(filePath: let filePath):
            return ""
            
        case .getDataUploadWorkbench:
            return "/offtake/workbench"
        }
    }
        
        
        
    
    /// 请求中使用的HTTP方法。
    public var method: Moya.Method {
        switch self {
            
            /// 注销账号
        case .deleteAccount:
            return .get
            
        case .uploadSiteFiles:
            return .post
        case .checkUpdate:
            return .get
        case .upDeviceToken:
            return .post
        case .login, .uploadImg,.uploadFile:
            return .post
            
        case .SmsCode:
            return .post
        case .loginpwd:
            return .post
        case .pwdReset:
            return .post
        case .getDataUploadWorkbench:
            return .get
        }
            
    }
        

    
    // MARK: - task
    public var task: Task {
        
        var posttoken = ""
        posttoken = UserDefaultsManager.queryDataForString(UserDefaultsName.User_token)
        switch self {
            
        case let .uploadSiteFiles(images):
            var imageDataArr = [MultipartFormData]()
            for image in images {
                let imageData = image.jpegData(compressionQuality: 0.1)
                let imageName = String(describing: Date())+".png"
                let imageForData = MultipartFormData(provider: .data(imageData!), name: "upload_file[]", fileName: imageName, mimeType: "image/png")
                imageDataArr.append(imageForData)
            }
            return .uploadCompositeMultipart(imageDataArr, urlParameters: taskResult(para: [String:String]()))
        case .checkUpdate:
            return .requestParameters(parameters: taskResult(para: [String:String]()), encoding: parameterEncoding)
        case .deleteAccount:
            return .requestParameters(parameters: taskResult(para: [String:String]()), encoding: parameterEncoding)
        case .login(userName: let userName, code: let code):
            let userNameForData = MultipartFormData(provider: .data(userName.utf8Encoded), name: "phone")
            let passWordForData = MultipartFormData(provider: .data(code.utf8Encoded), name: "code")
            let iosForData = MultipartFormData(provider: .data("ios".utf8Encoded), name: "term")
            return .uploadCompositeMultipart([userNameForData, passWordForData, iosForData], urlParameters: taskResult(para:["token": posttoken]))
        case let .SmsCode(phoneNumber):
            return .requestParameters(parameters: taskResult(para: ["phone": phoneNumber, "term": "ios"]), encoding: parameterEncoding)
        case .loginpwd(userName: let userName, passWord: let passWord):
            let userNameForData = MultipartFormData(provider: .data(userName.utf8Encoded), name: "phone")
            let passWordForData = MultipartFormData(provider: .data(passWord.utf8Encoded), name: "password")
            let iosForData = MultipartFormData(provider: .data("ios".utf8Encoded), name: "term")
            return .uploadCompositeMultipart([userNameForData, passWordForData, iosForData], urlParameters: taskResult(para:["token": posttoken]))
        case .pwdReset(phone: let phone, code: let code, password: let password, re_password: let re_password):
            let phoneForData = MultipartFormData(provider: .data(phone.utf8Encoded), name: "phone")
            let codeForData = MultipartFormData(provider: .data(code.utf8Encoded), name: "code")
            let passWordForData = MultipartFormData(provider: .data(password.utf8Encoded), name: "password")
            let repassWordForData = MultipartFormData(provider: .data(re_password.utf8Encoded), name: "re_password")
            let iosForData = MultipartFormData(provider: .data("ios".utf8Encoded), name: "term")
            return .uploadCompositeMultipart([phoneForData, codeForData, passWordForData, repassWordForData, iosForData], urlParameters: taskResult(para:["token": posttoken]))
        case .upDeviceToken(token: let token, come_from: let come_from, device: let device, login_account: let login_account):
            let come_from_idForData = MultipartFormData(provider: .data(come_from.utf8Encoded), name: "come_from")
            let deviceForData = MultipartFormData(provider: .data(device.utf8Encoded), name: "device")
            let login_accountData = MultipartFormData(provider: .data(login_account.utf8Encoded), name: "login_account")
            let iosForData = MultipartFormData(provider: .data("ios".utf8Encoded), name: "term")
            return .uploadCompositeMultipart([come_from_idForData, deviceForData, login_accountData, iosForData], urlParameters: taskResult(para:["token": token]))
        case .uploadImg(img: let img):
            let imageData = img.pngData()
            let imageName = String(describing: Date())+".png"
            let imageForData = MultipartFormData(provider: .data(imageData!), name: "image", fileName: imageName, mimeType: "image/png")
            return .uploadCompositeMultipart([imageForData], urlParameters: taskResult(para: [String:String]()))
        case .uploadFile(filePath: let filePath):
            let lastData = NSData(contentsOfFile: filePath as String)! as Data
            let fileForData = MultipartFormData(provider: .data(lastData), name: "file", fileName: "play.wav", mimeType: "wav")//upload_file
            return .uploadCompositeMultipart([fileForData], urlParameters: taskResult(para: [String:String]()))
            
            /// 数据上传工作台
        case .getDataUploadWorkbench:
                return .requestParameters(parameters: taskResult(para: [String:String]()), encoding: parameterEncoding)
        }
        
        
        
        
        
    }
    
    /// 用于参数编码的方法。
    public var parameterEncoding: ParameterEncoding {
        return URLEncoding.default
        
    }
    /// 提供用于测试的存根数据。
    public var sampleData: Data {
        fatalError()
    }
    
    public var headers: [String : String]? {
        return ["Accept-Encoding": "gzip"]
    }
    /// 是否执行Alamofire验证。默认为“false”。
    public var validate: Bool {
        return false
    }
    public func url(_ route: TargetType) -> String {
        return route.baseURL.appendingPathComponent(route.path).absoluteString
    }
    
    // 通用参数
    public var basePara: [String: String] {
        var token = ""
        
        token = UserDefaultsManager.queryDataForString(UserDefaultsName.User_token)
        let localVersion: String = (Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String) // 版本号
        let localBuildVersion: String = (Bundle.main.infoDictionary!["CFBundleVersion"] as! String)     // 构建号
        
        
        
        return ["term": "ios", "token": token, "device_model": UIDevice.current.modelName, "device_system": UIDevice.current.systemVersion, "version": localVersion, "buildVersion": localBuildVersion, "versionCode": localVersion, "device_id": self.getDevice_uuid()]
    }
    
    // 拼接通用参数到请求体
    func taskResult(para:[String: String]) -> [String: String] {
        
        // 获取所有请求参数
        var temp = [String: String]()
        for t2 in basePara { temp[t2.key] = basePara[t2.key] }
        if para.isEmpty == false {
            for t1 in para     { temp[t1.key] = para[t1.key] }
        }
        cn_Log(message: "参数输出：\n\(temp)")
        return temp
        
    }
    
    func getDevice_uuid() -> String {
        let keychain = Keychain(service: "com.DaNon.DaNengXunDian")
        let user_deviceToken = UserDefaultsManager.queryDataForString(UserDefaultsName.User_deviceToken)
        if let device_id = keychain[string: "yizhanggui_device_id"] {
            return device_id
        } else {
            keychain[string: "yizhanggui_device_id"] = user_deviceToken
        }
        
        return keychain[string: "yizhanggui_device_id"] ?? user_deviceToken
    }
}

import KeychainAccess

